#pragma region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU Lesser General Public License.
/// </copyright>
#pragma endregion

#pragma once
#include "_IClientEvents_CP.H"

class ATL_NO_VTABLE OSHClient : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<OSHClient, &__uuidof(OSHLibrary::Client)>,
	public IDispatchImpl<OSHLibrary::IClient, &__uuidof(OSHLibrary::IClient), &__uuidof(OSHLibrary::__OSH), /*wMajor =*/ -1, /*wMinor =*/ -1>,
	public IProvideClassInfo2Impl<&__uuidof(OSHLibrary::Client), NULL, &__uuidof(OSHLibrary::__OSH), -1, -1>,
	public IConnectionPointContainerImpl<OSHClient>,
	public CProxy_IClientEvents<OSHClient>
{
private:
	enum {
		HostPingInterval = 1000, // Time in ms
		OSHSourceNameTTL = 1000,       // Time in ms
		StopMonitoringTimeout = 50000,
		ConnectionFirstCheckTimeout = 1000,
		AlivePingTimeout = 60*1000, // 1 minute (time in ms)
	};

	GUID _hostGuid;
	CComBSTR _oshSourceName;

	ATL::CEvent _connectionFirstCheckEvent;
	ATL::CEvent _monitorThreadStopEvent;
	ATL::CHandle _monitorThread;
	//Timer _monitorTimer;
	bool _comInitialized;
	bool _destruction;

	HRESULT StartMonitoring();
	HRESULT StopMonitoring();
	static DWORD WINAPI MonitorThreadProc(OSHClient* self);

	bool IsConnected();
	HRESULT CheckConnection();
	HRESULT FireConnect(CComBSTR& sourceName);
	HRESULT FireDisconnect();

	HRESULT GetOSHSourceName(CComBSTR& sourceName);
	HRESULT GetOSHHost(OSHLibrary::IHost** oshHost);

public:
	OSHClient();
	virtual ~OSHClient();

	//void MonitorProc(Timer& timer);

	DECLARE_REGISTRY_RESOURCEID(IDR_OSHCLIENT)

	BEGIN_COM_MAP(OSHClient)
		COM_INTERFACE_ENTRY(OSHLibrary::IClient)
		COM_INTERFACE_ENTRY(IDispatch)
		COM_INTERFACE_ENTRY(IConnectionPointContainer)
		COM_INTERFACE_ENTRY(IProvideClassInfo)
		COM_INTERFACE_ENTRY(IProvideClassInfo2)
	END_COM_MAP()

	BEGIN_CONNECTION_POINT_MAP(OSHClient)
		CONNECTION_POINT_ENTRY(__uuidof(OSHLibrary::_IClientEvents))
	END_CONNECTION_POINT_MAP()

	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	
	void FinalRelease() 
	{
	}

public:

	// IClient Members
	STDMETHOD(get_State)(OSHLibrary::ConnectionStateEnum* state);
	STDMETHOD(get_SourceName)(BSTR* name);

	STDMETHOD(Connect)(BSTR hostGuid);
	STDMETHOD(Disconnect)();
	STDMETHOD(ActivateHost)();
	//STDMETHOD(SendMessage)(BSTR message);
};

OBJECT_ENTRY_AUTO(__uuidof(OSHLibrary::Client), OSHClient)
